﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using nHydrate.EFCore.DataAccess;
using Acme.Northwind.EFDAL;

namespace Acme.TestSite.Objects
{
	public abstract class BasePersistablePage : BasePage
	{
		#region Page Events

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);
			using (var context = new NorthwindEntities())
			{
				Mapper = new ORMMap(context);
				SetupBindings(context);
			}

			//Add dynamic validators to the page
			Mapper.GetValidators().ToList().ForEach(x => Page.Form.Controls.Add(x));
			Mapper.DataBind();
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			if (IsPostBack)
			{
				IEnumerable<Control> checkboxes = GetAllPageControls().Where(x => x is CheckBox);
				foreach (CheckBox item in checkboxes.Cast<CheckBox>())
				{
					if (Request.Form[item.UniqueID] == null)
						item.Checked = false;
				}

				IEnumerable<Control> radioboxes = GetAllPageControls().Where(x => x is RadioButton);
				foreach (RadioButton item in radioboxes.Cast<RadioButton>())
				{
					if (Request.Form[item.UniqueID] == null)
						item.Checked = false;
				}
			}
		}

		#endregion

		#region Properties

		public ORMMap Mapper { get; private set; }

		#endregion

		#region Events

		public event EventHandler DataSavedSucess;
		public event EventHandler<DataSavingEventArgs> DataSaving;
		public event EventHandler<DataErrorEventArgs> DataSavedFailed;

		protected virtual void OnDataSavedSucess(EventArgs e)
		{
			if (DataSavedSucess != null)
				DataSavedSucess(this, e);
		}

		protected virtual void OnDataSaving(DataSavingEventArgs e)
		{
			if (DataSaving != null)
				DataSaving(this, e);
		}

		protected virtual void OnDataSavedFailed(DataErrorEventArgs e)
		{
			if (DataSavedFailed != null)
				DataSavedFailed(this, e);
		}

		#endregion

		#region Methods

		protected abstract void SetupBindings(NorthwindEntities context);

		protected virtual NHEntityObject CreateObject(NorthwindEntities context)
		{
			return null;
		}

		public virtual void SaveData(object sender, EventArgs e)
		{
			try
			{
				if (!IsValid)
				{
					OnDataSavedFailed(new DataErrorEventArgs());
					return;
				}

				using (var context = new NorthwindEntities())
				{
					SetupBindings(context);
					Mapper.DataPersist();

					var eventParam = new DataSavingEventArgs {Context = context};
					OnDataSaving(eventParam);
					if (eventParam.Cancel)
					{
						if (string.IsNullOrEmpty(eventParam.ErrorMessage))
							throw new Exception("An error message must be set when the save is cancelled.");

						var validator = new CustomValidator {IsValid = false, ErrorMessage = eventParam.ErrorMessage};
						Validators.Add(validator);

						OnDataSavedFailed(new DataErrorEventArgs {ErrorMessage = eventParam.ErrorMessage});

						return; //If cancelled DO NOT SAVE
					}
					context.SaveChanges();
				}

				OnDataSavedSucess(new EventArgs());
			}
			catch (Exception ex)
			{
				var validator = new CustomValidator {IsValid = false, ErrorMessage = ex.Message};
				Validators.Add(validator);

				OnDataSavedFailed(new DataErrorEventArgs {ErrorMessage = ex.Message});
			}
		}

		#endregion
	}
}